import threading
import time

import traci
import sumolib
import numpy
import function
import json
from websocket_server import WebsocketServer, logging
from websocket.server import Server


def startSumo():
    sumoBinary = sumolib.checkBinary("sumo-gui")
    traci.start([sumoBinary, "-c", 'yantai.sumocfg'])

    step_time = traci.simulation.getTime() * 1000  # 转换为毫秒
    traci.simulationStep()
    step_time_new = traci.simulation.getTime() * 1000
    step_length = numpy.float64(step_time_new - step_time) / 1000
    print("Step length is:", step_length, "s")
    return step_length


def startExtractData(step_length):
    websocket = Server()
    # traci.vehicle.setLaneChangeMode('FH1101', 0b000000000000)
    # traci.vehicle.setSpeedMode("FH1101", 00000)
    traci.simulationStep()
    # traci.vehicle.setLaneChangeMode('FH1101', 0.5)
    while traci.simulation.getMinExpectedNumber() > 0:
        traci.simulationStep()
        for veh_id in traci.vehicle.getIDList():
            lng, lat, angle = function.outPut(veh_id)
            msg = {
                "id": veh_id,
                "lng": lng,
                "lat": lat,
                "angle": angle
            }
            # function.forwardCollision('FH1101', 'FH1102')
            # function.innormalVeh('FH1101')
            function.personEvent('FH1101')
            websocket.send(json.dumps(msg))
        for person_id in traci.person.getIDList():
            lng, lat, angle = function.outPutPerson(person_id)
            msg = {
                "id": person_id,
                "lng": lng,
                "lat": lat,
                "angle": angle
            }
            websocket.send(json.dumps(msg))
        time.sleep(step_length)


def startAll():
    step_length = startSumo()
    startExtractData(step_length)


if __name__ == "__main__":
    s = Server()
    server = WebsocketServer(host='0.0.0.0', port=13254, loglevel=logging.INFO)
    s.add_server(server)
    t = threading.Thread(target=server.run_forever)
    thread = threading.Thread(target=startAll)
    try:
        # 在start子线程后直接退出主线程
        thread.start()
        t.start()
    except KeyboardInterrupt:
        traci.close()
